home *** CD-ROM | disk | FTP | other *** search
/ Programming Sound Cards / Programming Sound Cards.iso / sound_56 / readnote.asm < prev    next >
Assembly Source File  |  1995-01-01  |  45KB  |  1,160 lines

  1. model large,pascal
  2.  
  3. .DATA
  4. noeffect  EQU    dw offset checkonlyPara  ; no effect
  5. noeffect2 EQU    dw offset handlenothing  ; nothing to do for this effect here ...
  6.  
  7. INCLUDE GENERAL.DEF
  8. EXTRN ORDER      : BYTE
  9. EXTRN CHANNEL    : TCHANNEL
  10. EXTRN PATTERN    : WORD
  11. EXTRN INSTRUMENTs : WORD
  12. EXTRN usedchannels : BYTE
  13. EXTRN curline      : BYTE
  14. EXTRN curOrder     : BYTE
  15. EXTRN curPattern   : BYTE
  16. EXTRN curtick      : BYTE
  17. EXTRN curspeed     : BYTE
  18. EXTRN Userate   : WORD
  19. EXTRN loopS3M      : BYTE
  20. EXTRN lastorder    : BYTE
  21. EXTRN EndOfSong    : BYTE
  22. EXTRN gvolume      : BYTE
  23. EXTRN amigalimits  : BYTE
  24. EXTRN sinuswave    : BYTE
  25. EXTRN rampwave     : BYTE
  26. EXTRN Squarewave   : BYTE
  27. EXTRN Insnum       : WORD
  28. EXTRN patterndelay : BYTE
  29. EXTRN Ploop_on     : BYTE
  30. EXTRN Ploop_no     : BYTE
  31. EXTRN Ploop_to     : BYTE
  32. EXTRN patEMShandle : WORD
  33. EXTRN FrameSeg     : WORD
  34. EXTRN patlength    : WORD
  35.  
  36.       wavetab      DW offset sinuswave
  37.                    DW offset rampwave
  38.                    DW offset squarewave   ; looks not like a square but anyway
  39.                    ; 'random wave' is not a table, but a call for a random number !
  40.  
  41.       st3periods   dw 1712,1616,1524,1440,1356,1280,1208,1140,1076,1016, 960, 907
  42.  
  43.       ; we have to init all the effects :
  44.       initeffects  noeffect
  45.                    dw offset setspeed       ; effect 'A'  ok !
  46.                    dw offset jump2order     ; effect 'B'  ok !
  47.                    dw offset patternbreak2  ; effect 'C'  ok !
  48.                    dw offset VolumeEfcts    ; effect 'D'  ok !
  49.                    dw offset Pitchdowns     ; effect 'E'  ok !
  50.                    dw offset Pitchups       ; effect 'F'  ok !
  51.                    dw offset Portamento     ; effect 'G'  ok !
  52.                    dw offset vibrato        ; effect 'H'  ok !
  53.                    dw offset Tremor         ; effect 'I'   <- shity can't get it :( ... ugly implementation
  54.                    dw offset Arpeggio       ; effect 'J'  ok !
  55.                    dw offset Vib_Vol        ; effect 'K'  ok !
  56.                    dw offset Port_Vol       ; effect 'L'  ok !
  57.                    noeffect
  58.                    noeffect
  59.                    noeffect
  60.                    noeffect
  61.                    dw offset Retrigg        ; effect 'Q'  ok !
  62.                    dw offset Tremolo        ; effect 'R'  ok !
  63.                    dw offset Specialsets    ; effect 'S'  look at special 1
  64.                    dw offset setTempo       ; effect 'T'  ok !
  65.                    dw offset vibrato        ; effect 'U'  ok ! (here equal to vibrato)
  66.                    dw offset globalvolume   ; effect 'V'  ok !
  67.  
  68.       ; Ok now some tables for multichoise effects (e.g. 'Syx' but also 'Dxy',E,F)
  69.       ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  70.       special1     noeffect                   ; S0? - nothin
  71.                    noeffect                   ; set filter -> not implemented (by ST3)
  72.                    noeffect                   ; set glissando -> not implemented (by ST3)
  73.                    noeffect                   ; set finetune -> not here ! look special2
  74.                    dw offset setvibwav     ;OK !
  75.                    dw offset settremwav    ;OK !
  76.                    noeffect                   ; does not exist
  77.                    noeffect                   ; does not exist
  78.                    noeffect                   ; maybe later (it's E8x - panning )
  79.                    noeffect                   ; does not exist
  80.                    noeffect                   ; stereo control not implemented
  81.                    dw offset cmdPatloop    ;
  82.                    dw offset InitNotecut   ;
  83.                    dw offset InitNotedelay ;
  84.                    dw offset InitPatdelay  ;
  85.                    noeffect                   ; funkrepeat -> not implemented
  86.  
  87.       retrig_dif   dw offset nosld            ; all done ...
  88.                    dw offset slddown
  89.                    dw offset slddown
  90.                    dw offset slddown
  91.                    dw offset slddown
  92.                    dw offset slddown
  93.                    dw offset use2div3
  94.                    dw offset use1div2
  95.                    dw offset nosld
  96.                    dw offset sldup
  97.                    dw offset sldup
  98.                    dw offset sldup
  99.                    dw offset sldup
  100.                    dw offset sldup
  101.                    dw offset use3div2
  102.                    dw offset use2times
  103.  
  104.       ; and some effects we have to handle after reading vol/inst/note
  105.       ; maybe refresh etc. - remember MODplayer ...
  106.       ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  107.       handleeffects  noeffect2              ; really no effect ;)
  108.                      noeffect2
  109.                      noeffect2
  110.                      noeffect2
  111.                      dw offset Hdl_Volfx    ; effect 'D'  ok!
  112.                      dw offset Hdl_pitchdwn ; effect 'E'  ok!
  113.                      dw offset Hdl_pitchup  ; effect 'F'  ok!
  114.                      dw offset Hdl_porta    ; effect 'G'  ok!
  115.                      dw offset Hdl_Vibrato  ; effect 'H'  ok!
  116.                      noeffect2
  117.                      dw offset Hdl_arpeggio ; effect 'J'  ok!
  118.                      dw offset hdl_Vib_Vol  ; effect 'K'  ok!
  119.                      dw offset Hdl_Port_Vol ; effect 'L'  ok!
  120.                      noeffect2
  121.                      noeffect2
  122.                      dw offset Hdl_setsmpofs ; effect 'O'  ok!
  123.                      noeffect2
  124.                      noeffect2
  125.                      dw offset Hdl_tremolo  ; effect 'R'  ok!
  126.                      dw offset Hdl_Special  ; effect 'S'  look at special 2
  127.                      noeffect2
  128.                      dw offset Hdl_Vibrato  ; effect 'U'  ok! (here equal to vibrato
  129.                      noeffect2
  130.  
  131.       ; Ok now some tables for multichoise effects (e.g. 'Syx' but also 'Dxy',E,F)
  132.       ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  133.       Vol_cmd2nd     noeffect2
  134.                      noeffect2
  135.                      dw offset FineVSlideDwn
  136.                      dw offset FineVSlideUp
  137.       Pitdwn_cmd2nd  noeffect2
  138.                      dw offset Finepitch_down
  139.                      dw offset XFinepitch_down
  140.       Pitup_cmd2nd   noeffect2
  141.                      dw offset Finepitch_up
  142.                      dw offset XFinepitch_up
  143.  
  144.       special2     noeffect2                  ; S0? - nothin
  145.                    noeffect2                  ; set filter -> not implemented (by ST3)
  146.                    noeffect2                  ; set glissando -> not implemented (by ST3)
  147.                    dw offset Hdl_finetune
  148.                    noeffect2                  ; not here -> special 1
  149.                    noeffect2                  ; not here -> special 1
  150.                    noeffect2                  ; does not exist
  151.                    noeffect2                  ; does not exist
  152.                    noeffect2                  ; not here -> special 1
  153.                    noeffect2                  ; does not exist
  154.                    noeffect2                  ; stereo control -> not implemented (by ST3)
  155.                    noeffect2                  ; not here -> special 1
  156.                    noeffect2                  ; not here -> special 1
  157.                    noeffect2                  ; not here -> special 1
  158.                    dw offset Hdl_patterndly
  159.                    noeffect2                  ; funkrepeat -> not implemented
  160.  
  161.       chnCounter   db ?
  162.       jump2flag    db ?
  163.       jump2where   db ?
  164.       breakflag    db ?
  165.       break2where  db ?
  166.       pLoop_now    db ?
  167.       gvolFlag     db ?
  168.       newgvol      db ?
  169.       ; to save portamento values :
  170.       portaFlag    db ?
  171.       Period_old   dw ?
  172.       sStep_old    dd ?
  173.       ; a little one for arpeggio :
  174.       arp_chg      db ?
  175.       ; save effect,parameter for patterndelay
  176.       sav_cmd      dw ?
  177.       sav_para     db ?
  178.       ; now some variables I added after I found out those amazing things
  179.       ; about patterndelay
  180.       inpatterndly db ?   ;<- call 'readnotes' inside a patterndelay, if then ignore all
  181.                           ;notes/inst/vol !
  182.       curnote      db ?   ;<- normaly it will be a copie of es:[di], but in
  183.                           ; patterndelay =0 <- ignore note =)
  184.       curinst      db ?   ; the same thing for instrument
  185.       curVol       db ?   ; and for volume
  186.  
  187. ENDS
  188.  
  189. .CODE
  190. .386
  191.  
  192. PUBLIC READNEWNOTES
  193. PUBLIC SetupNewInst
  194. PUBLIC SetNewNote
  195. EXTRN  SET_TEMPO
  196. EXTRN  EMSMAP : FAR       ; <- somehow that does not work (assembler creats:
  197.                           ;    "push cs" + "near call", but that's wrong !!!
  198.  
  199. CalcFrequStep  MACRO
  200. ; IN: ax = period
  201. ; OUT: destroys EDX,EBX
  202.  
  203.              and     eax,0ffffh      ; clear upper 16bit
  204.              xor     edx,edx
  205.              mov     dx,[Userate]
  206.              mul     edx             ; EAX = Userate*Period
  207.              mov     ebx,eax
  208.  
  209.              xor     edx,edx
  210.              mov     dx,0dah
  211.              mov     eax,77900000h   ; EDX:EAX = 1712*8363*10000h
  212.  
  213.              div     ebx
  214.  
  215.              ;        1712 * 8363 * 10000h
  216.              ; EAX = ----------------------
  217.              ;        Userate * Period
  218. ENDM
  219.  
  220. CalcPeriod   macro
  221. local notbelow,notabove
  222. ; IN:  AL - Note (higher 4=name,lower 4=octave)
  223. ;      FS - Segment of instrument
  224. ; OUT: AX = Period
  225. ; DESTROYs: BX,CL
  226.              ; calc speriod (with st3 finetune) :
  227.              mov     bl,al
  228.              mov     cl,al
  229.              shr     cl,4
  230.              xor     bh,bh
  231.              and     bl,0fh
  232.              shl     bl,1
  233.              ; ok calculate the period
  234.              mov     ax,[st3periods+bx]
  235.              shl     ax,4                 ; period(note)*16
  236.              shr     ax,cl                ; period(note)*16 >> octave(note)
  237.              mov     dx,8363
  238.              mul     dx                   ; dx:ax = 8363*period(note)*16 >> octave(note)
  239.              mov     bx,fs:[TInstrument.c2speed]
  240.              div     bx
  241.  
  242.              ;       8363*(period(note)*16 shr octave(note))
  243.              ; ax = --------------------------------------
  244.              ;            C2Speed of current Sample
  245.  
  246.              ; Now check borders :
  247.              cmp     ax,[channel.lower_border+si]
  248.              jnb     notbelow
  249.              mov     ax,[channel.lower_border+si]
  250. notbelow:    cmp     ax,[channel.upper_border+si]
  251.              jna     notabove
  252.              mov     ax,[channel.upper_border+si]
  253. notabove:
  254. endM
  255.  
  256. CheckPara0 MACRO
  257. local cp
  258.            cmp      al,0
  259.            jnz      cp
  260.            mov      al,[channel.parameter+si]
  261. cp:        mov      [channel.parameter+si],al
  262. ENDM
  263.  
  264. CheckPara0not MACRO
  265. local cp
  266.               cmp      al,0
  267.               je       cp
  268.               mov      [channel.parameter+si],al
  269. cp:
  270. ENDM
  271.  
  272. SetupNewInst PROC NEAR
  273. ; IN : AL = number of new instrument
  274. ;      SI = offset to channel
  275. ;      DS = Dataseg
  276. ;
  277. ; DESTROYs FS,BX,AX,DX
  278. ;
  279.              dec     al
  280.              mov     bl,al
  281.              xor     bh,bh
  282.              shl     bx,2
  283.              xor     ah,ah
  284.              add     bx,ax
  285.              mov     ax,ds:[Instruments+2]
  286.              add     bx,ax
  287.              mov     fs,bx
  288.              mov     [channel.instrSEG+si],bx
  289.              mov     al,fs:[TInstrument.vol]
  290.              cmp     al,64
  291.              jb      volwell
  292.              mov     al,63
  293. volwell:     mul     [gvolume]
  294.              shr     ax,6
  295.              mov     [channel.SampleVol+si],al
  296.              mov     ax,fs:[TInstrument.memseg]
  297.              mov     [channel.sampleSEG+si],ax
  298.              mov     al,fs:[TInstrument.flags]
  299.              and     al,00000001b       ; bit 0 - loop sample ?
  300.              mov     [channel.sLoopflag+si],al
  301.              mov     ax,fs:[TInstrument.loopbeg]
  302.              mov     [channel.sLoopstart+si],ax
  303.              mov     ax,fs:[TInstrument.loopend]
  304.              cmp     [channel.sLoopflag+si],1
  305.              je      weloop                            ; =:)
  306.              mov     ax,fs:[TInstrument.slength]     ; <- we don't loop :( anyway ...
  307. weLoop:      mov     [channel.sLoopend+si],ax
  308.              ; calc period borders
  309.              mov     bx,fs:[TInstrument.c2speed]
  310.              cmp     bx,0
  311.              jne     c2speedok
  312.              ; c2speed = 0 -> don't play it !! it's wrong !
  313.              mov     [channel.InstrNo+si],0
  314. c2speedok:   mov     [channel.ssmpstart+si],0  ; reset start value
  315.              cmp     [amigalimits],1
  316.              je      takeamigalimits
  317.              ; B-7 :
  318.              mov     ax,907 * 16 / 128   ; period(note)*16 >> 7
  319.              mov     dx,8363
  320.              mul     dx                   ; dx:ax = 8363*period(note)*16 >> octave(note)
  321.              div     bx
  322.              mov     [channel.lower_border+si],ax
  323.              ; C-0 :
  324.              mov     ax,1712 * 16         ; period(note)*16 >> 0
  325.              mov     dx,8363
  326.              mul     dx                   ; dx:ax = 8363*period(note)*16 >> octave(note)
  327.              cmp     bx,3500
  328.              jb      c2below
  329.              div     bx
  330.              mov     [channel.upper_border+si],ax
  331.              jmp     after1
  332. c2below:     mov     bx,3500
  333.              div     bx
  334.              mov     [channel.upper_border+si],ax
  335.              jmp     after1
  336. takeamigalimits:
  337.              ; first C-3 :
  338.              mov     ax,1712 * 16 / 8     ; period(note)*16 >> 3
  339.              mov     dx,8363
  340.              mul     dx                   ; dx:ax = 8363*period(note)*16 >> octave(note)
  341.              div     bx
  342.              mov     [channel.upper_border+si],ax
  343.              ; then B-5 :
  344.              mov     ax,907 * 16 / 32     ; period(note)*16 >> 5
  345.              mov     dx,8363
  346.              mul     dx                   ; dx:ax = 8363*period(note)*16 >> octave(note)
  347.              div     bx
  348.              mov     [channel.lower_border+si],ax
  349. after1:      mov     al,[curInst]
  350.  
  351.              ret
  352. ENDP
  353.  
  354. SetNewNote   PROC NEAR
  355. ; IN: AL = note & octave
  356. ;     SI = offset to channel
  357. ;
  358. ; DESTROYs: EAX,EBX,EDX,FS,CX
  359. ;
  360.              ; clear it first - just to make sure we really set it
  361.              mov     [channel.speriod+si],0
  362.              cmp     [channel.instrNo+si],0
  363.              je      after2                  ; if there's no instrumnet
  364.              ; set pointer to instrument
  365.              push    ax
  366.              mov     ax,[channel.instrSEG+si]
  367.              mov     fs,ax
  368.              pop     ax
  369.              cmp     fs:[TInstrument.Typ],1  ; only calc if instrument does exist
  370.              jne     after2
  371.  
  372.              calcperiod
  373.  
  374.              mov     [channel.speriod+si],ax
  375.  
  376.              ; now step calculations :
  377.              CalcFrequStep
  378.  
  379.              mov     [channel.sStep+si],EAX
  380.  
  381.              cmp     [portaFlag],1
  382.              je      after2             ; it's porta, do not restart !
  383.              ; restart instrument
  384.              xor     ebx,ebx
  385.              mov     bx,[channel.sSmpstart+si]
  386.              shl     ebx,16
  387.              mov     [channel.sCurpos+si],ebx
  388.              mov     [channel.enabled+si],1
  389. after2:      ret
  390. ENDP
  391.  
  392. ; put next notes into channels
  393. READNEWNOTES PROC NEAR
  394.              mov     [jump2flag],0
  395.              mov     [breakflag],0
  396.              mov     [gvolFlag],0
  397.              mov     [Ploop_now],0
  398.              mov     [inpatterndly],0
  399.              cmp     [patterndelay],0
  400.              je      nopatdly
  401.              mov     [inpatterndly],1
  402. nopatdly:    mov     al,[usedchannels]
  403.              mov     [chnCounter],al
  404.              ; get next postion in current pattern
  405.              mov     al,[usedchannels]
  406.              mov     ah,al
  407.              shl     al,2
  408.              add     al,ah        ; al = 5*[usedchannels]
  409.              mov     ah,[curline]
  410.              mul     ah
  411.              ; ok that was the offset :
  412.              mov     di,ax
  413.              ; now the segment of current pattern :
  414.              xor     bh,bh
  415.              mov     bl,[curorder]
  416.              mov     bl,[order+bx]
  417.              cmp     bl,254
  418.              jae     nextorder
  419.              shl     bx,1
  420.              mov     ax,[pattern+bx]
  421.              or      ax,ax
  422.              jz      nopatloop
  423.              cmp     ax,0C000h
  424.              jb      noEMSpattern
  425.              push    ax
  426.              push    di
  427.              ; Set page number:
  428.              mov     ah,044h
  429.              xor     bx,bx
  430.              mov     bl,al              ; bx = logical page
  431.              xor     al,al              ; al = physical page
  432.              mov     dx,[patEMShandle]  ; dx = handle
  433.              int     67h
  434.              cmp     ah,0
  435.              je      noemsprob
  436.              mov     dl,0
  437.              div     dl         ; <- cause a "div by 0" because EMSdriver does not work correct
  438. noemsprob:   pop     di
  439.              pop     ax
  440.              ; change offset to part #(ah and 0fh)
  441.              shr     ax,8
  442.              and     al,3fh             ; bit 13-8 = partno.
  443.              xor     ah,ah
  444.              mov     dx,[patlength]
  445.              mul     dx                 ; ax = partno * pattern length
  446.              add     di,ax
  447.              mov     ax,[frameSEG]
  448. noemspattern:mov     es,ax
  449.              ; ES:DI - pointer to current position in current pattern
  450.              xor     si,si               ; extra channel offset (running through the channels)
  451. chnLoop:     cmp     [channel.channeltyp+si],2
  452.              ja      donothing           ; <- for adlib channels
  453.              mov     [portaFlag],0      ; <- set Flag back
  454.              ; ok first do read current note,inst,vol -> if in patterndelay then ignore them !
  455.              mov     [curNote],0ffh
  456.              mov     [curInst],00h
  457.              mov     [curVol] ,0ffh
  458.              cmp     [inpatterndly],1
  459.              je      ignorethem
  460.              mov     al,es:[di]
  461.              mov     [curNote],al
  462.              mov     al,es:[di+1]
  463.              mov     [curInst],al
  464.              mov     al,es:[di+2]
  465.              mov     [curVol],al
  466. ignorethem:  ; read effects - it may change the read instr/note !
  467.              ; ~~~~~~~~~~~~
  468.              mov     al,es:[di+3]        ; read effect number
  469.              xor     ah,ah
  470.              shl     ax,1
  471.              mov     [channel.continueEf+si],0
  472.              cmp     ax,2*8              ; Vibrato ...
  473.              je      checkifcontV
  474.              cmp     ax,2*11             ; Vibrato Volefcs
  475.              je      checkifcontV
  476.              cmp     ax,2*21             ; fine Vibrato
  477.              je      checkifcontV
  478.              ; -> no vibrato effect, so check if last row there was one ...
  479.              ; if there was - do refresh sStep
  480.              cmp     [channel.command+si],2*8      ; was vibrato
  481.              je      Vibend
  482.              cmp     [channel.command+si],2*21     ; was fine vibrato
  483.              je      Vibend
  484.              cmp     [channel.command+si],2*11     ; was vibrato+volef
  485.              jne     noVibend
  486.              ; refresh frequency
  487. vibend:      push    ax
  488.              mov     ax,[channel.OldPeriod+si]
  489.              mov     [channel.sPeriod+si],ax
  490.              cmp     ax,0
  491.              je      novibcalc
  492.              CalcFrequStep
  493.              mov     [channel.sStep+si],EAX
  494. novibcalc:   pop     ax
  495. novibend:    cmp     ax,2*18             ; Tremolo ...
  496.              je      checkifcontTrm
  497.              cmp     ax,2*10             ; Arpeggio ...
  498.              je      checkifcontA
  499.              ; - currently no arpeggio, but arpeggio was last row ?
  500.              ; if there was - set sStep = Step0 (refresh frequ)
  501.              cmp     [channel.command+si],2*10
  502.              jne     noarpegend
  503.              ; arpeggio ends :
  504.              push    ax
  505.              mov     eax,[channel.step0+si]
  506.              mov     [channel.sStep+si],eax
  507.              pop     ax
  508. noarpegend:  cmp     ax,2*17               ; Note retrigg
  509.              je      checkifcontRetr
  510. aftercontcheck:
  511.              mov     bx,[channel.command+si]
  512.              mov     [sav_cmd],bx               ; to save it for pattern delay ...
  513.              mov     [channel.command+si],ax
  514.              mov     [channel.cmd2nd+si],0
  515.              cmp     al,44
  516.              jbe     noproblem
  517.              mov     [channel.command+si],0
  518.              xor     ax,ax
  519. noproblem:   mov     bx,ax
  520.              mov     al,es:[di+4]        ; read effect parameter
  521.              jmp     [initeffects+bx]
  522. back2reality:
  523.  
  524. effectdone:  ; read instrument
  525.              ; ~~~~~~~~~~~~~~~
  526.              ; reinit instrument data but don't restart !
  527.              mov     al,[curInst]
  528.              cmp     al,00
  529.              je      no_newinstr
  530.  
  531.              ; ------------------ check if instrument does exist
  532.              push    ax
  533.              dec     al
  534.              mov     bl,al
  535.              xor     bh,bh
  536.              shl     bx,2
  537.              xor     ah,ah
  538.              add     bx,ax
  539.              mov     ax,ds:[Instruments+2]
  540.              add     bx,ax
  541.              mov     fs,bx
  542.              cmp     fs:[TInstrument.typ],1
  543.              je      instok
  544.              pop     ax
  545.              xor     al,al
  546.              mov     [curInst],al
  547.              jmp     no_newinstr
  548. instok:      pop     ax
  549.  
  550.              comment #
  551.              cmp     [channel.enabled+si],0       ; if channel is disabled then restart definitly
  552.              je      restart
  553.              cmp     [channel.InstrNo+si],al      ; but if it's enabled & same instrno then don't restart
  554.              je      dontrestart
  555. restart:     cmp     [portaFlag],1                ; and if portamento then don't restart ;)
  556.              je      dontrestart
  557.              mov     bx,[channel.sSmpstart+si]
  558.              mov     [channel.sCurpos+si],bx
  559. dontrestart:
  560.              #
  561.  
  562.              mov     [channel.InstrNo+si],al
  563.              call near ptr SetupNewInst
  564. no_newinstr: ; read note ...
  565.              ; ~~~~~~~~~~~~~
  566.              mov     al,[curNote]
  567.              cmp     al,0ffh
  568.              je      no_newnote
  569.              cmp     al,0feh
  570.              jne     normal_note
  571.              mov     [channel.enabled+si],0     ; stop mixing
  572.              jmp     no_newnote
  573. normal_note: mov     [channel.Note+si],al
  574.              call near ptr SetNewNote
  575. no_newnote:  ; read volume - last but not least ;)
  576.              ; ~~~~~~~~~~~
  577.              mov     al,[curVol]
  578.              cmp     al,0ffh
  579.              je      no_vol
  580.              cmp     al,64
  581.              jb      volok
  582.              mov     al,63
  583. volok:       mul     [gvolume]
  584.              shr     ax,6
  585.              mov     [channel.SampleVol+si],al
  586.  
  587. no_vol:      ; ok now the effect handling after reading vol/instr/note
  588.              mov     bx,[channel.command+si]
  589.              jmp     [handleeffects+bx]
  590. handlenothing:
  591.  
  592. donothing:   add     di,5                ; to next channel in pattern
  593.              add     si,size Channel     ; to next channel in channel mix info
  594.              dec     [chnCounter]        ; one channel done
  595.              jnz     chnLoop
  596.              cmp     [gvolFlag],0
  597.              je      nonewglobal
  598.              mov     al,[newgvol]
  599.              mov     [gvolume],al
  600. nonewglobal: mov     al,[curspeed]
  601.              mov     [curtick],al
  602.              cmp     [breakflag],1
  603.              je      patternbreak
  604.              cmp     [jump2flag],1
  605.              je      jumporder
  606.              cmp     [Ploop_now],1
  607.              je      dopatloop
  608. nopatloop:   inc     [curline]
  609.              cmp     [curline],64
  610.              jne     only_next
  611.              ; ok - next order ...
  612.              mov     [curline],0
  613. nextorder:   inc     [curorder]
  614. otherorder:  mov     [Ploop_to],0
  615.              mov     al,[lastorder]
  616.              cmp     [curorder],al
  617.              ja      end_reached
  618. doloop:      xor     bh,bh
  619.              mov     bl,[curorder]
  620.              mov     al,[Order+bx]
  621.              cmp     al,254
  622.              jae     nextorder
  623.              mov     [curpattern],al
  624. only_next:   ret
  625.  
  626. patternbreak:mov     al,[break2where]
  627.              mov     [curline],al
  628.              jmp     nextorder
  629.  
  630. jumporder:   mov     [curline],0
  631.              mov     al,[jump2where]
  632.              mov     [curorder],al
  633.              jmp     otherorder
  634.  
  635. dopatloop:   dec     [Ploop_no]
  636.              jz      patloopends
  637.              mov     al,[Ploop_to]
  638.              mov     [curline],al
  639.              jmp     only_next
  640. patloopends: mov     al,[curline]
  641.              inc     al
  642.              mov     [PLoop_to],al
  643.              mov     [Ploop_on],0
  644.              jmp     nopatloop
  645.  
  646. end_reached: cmp     [loopS3M],1
  647.              jne     donotloop
  648.              mov     [curorder],0
  649.              jmp     doloop
  650. donotloop:   mov     [EndOfSong],1
  651.              jmp     only_next
  652.  
  653. checkifcontV:  ; check if continue Vib/Vib_vol
  654.              cmp     [curNote],0feh
  655.              jb      aftercontcheck
  656.              cmp     [channel.command+si],11*2  ; command before was vibrato
  657.              je      checkok1
  658.              cmp     [channel.command+si],21*2  ; command before was fine vibrato
  659.              je      checkok1
  660.              cmp     [channel.command+si],8*2   ; command before was vibrato+volef
  661.              jne     aftercontcheck
  662. checkok1:    mov     [channel.continueEf+si],1
  663.              jmp     aftercontcheck
  664.  
  665. checkifcontA:     ; check if continue Arpeg
  666.              cmp     [curNote],0feh
  667.              jb      aftercontcheck
  668. checkifcontTrm:   ; check if continue a tremolo
  669. checkifcontRetr:  ; check if continue a note retrig
  670.              cmp     [channel.command+si],ax
  671.              jne     aftercontcheck
  672.              mov     [channel.continueEf+si],1
  673.              jmp     aftercontcheck
  674.  
  675. ; Effects :
  676. ; ~~~~~~~~~
  677.  
  678. checkonlyPara: checkPara0
  679.                jmp      back2reality
  680.  
  681. setspeed:      ; effect 'A'
  682.                checkPara0not
  683.                cmp      al,0                ; speed = 0 does not exist
  684.                je       back2reality
  685.                mov      [curspeed],al
  686.                jmp      back2reality
  687. jump2order:    ; effect 'B'
  688.                checkPara0not
  689.                mov      [jump2flag],1
  690.                mov      [jump2where],al
  691.                jmp      back2reality
  692. patternbreak2: ; effect 'C'
  693.                checkPara0not
  694.                mov      [breakflag],1
  695.                mov      ah,al
  696.                and      al,0fh
  697.                shr      ah,4
  698.                AAD
  699.                mov      [break2where],al
  700.                jmp      back2reality
  701. VolumeEfcts:   ; effect 'D' or jump from dual commands ...
  702.                checkPara0
  703.                mov      ah,al
  704.                shr      ah,4
  705.                cmp      ah,0fh
  706.                jne      nofinevoldown
  707.                cmp      al,0f0h
  708.                je       volup
  709.                ; normal fine volume down   DFx
  710.                mov      [channel.cmd2nd + si],04
  711.                jmp      back2reality
  712. nofinevoldown: mov      ah,al
  713.                and      ah,0fh
  714.                cmp      ah,0fh
  715.                jne      nofinevolup
  716.                cmp      al,0fh
  717.                je       voldown
  718.                ; normal fine volume up     DxF
  719.                mov      [channel.cmd2nd + si],06
  720.                jmp      back2reality
  721. nofinevolup:   mov      ah,al
  722.                and      ah,00fh
  723.                jz       notVslidedown
  724.                ; normale slide down effect D0x
  725. voldown:       mov      [channel.cmd2nd + si],00
  726.                jmp      back2reality
  727. notVslidedown: ; normal slide up effect    Dx0
  728. volup:         mov      [channel.cmd2nd + si],02
  729.                jmp      back2reality
  730. Pitchdowns:    ; effect 'E'
  731.                checkPara0
  732.                cmp      al,0DFh      ; al is parameter
  733.                ja       extraptdowns
  734.                mov      [channel.cmd2nd + si],00
  735.                jmp      back2reality
  736. extraptdowns:  cmp      al,0EFh
  737.                ja       Finepitchdown
  738.                ; extra fine slides
  739.                mov      [channel.cmd2nd + si],04
  740.                jmp      back2reality
  741. Finepitchdown: mov      [channel.cmd2nd + si],02
  742.                jmp      back2reality
  743. Pitchups:      ; effect 'F'
  744.                checkPara0
  745.                cmp      al,0DFh      ; al is parameter
  746.                ja       extraptups
  747.                mov      [channel.cmd2nd + si],00
  748.                jmp      back2reality
  749. extraptups:    cmp      al,0EFh
  750.                ja       Finepitchup
  751.                ; extra fine slides
  752.                mov      [channel.cmd2nd + si],04
  753.                jmp      back2reality
  754. Finepitchup:   mov      [channel.cmd2nd + si],02
  755.                jmp      back2reality
  756. Portamento:    ; effect 'G'
  757.                checkPara0not
  758.                cmp      al,0
  759.                je       nonewPortpara
  760.                mov      [channel.PortPara+si],al
  761. nonewPortpara: mov      [portaFlag],1
  762.                ; check first if portamento really possible:
  763.                cmp      [channel.enabled+si],0
  764.                je       stopporta
  765.                cmp      [curNote],0feh
  766.                jae      back2reality    ; <- continue portamento
  767.                ; now save some values (we wanna slide from ...)
  768.                mov      eax,[channel.sStep+si]
  769.                mov      [sStep_old],eax
  770.                mov      ax,[channel.sPeriod+si]
  771.                mov      [Period_old],ax
  772.                jmp      back2reality
  773. stopporta:     mov      [channel.command+si],0   ;<-noeffect
  774.                mov      [portaFlag],0
  775.                jmp      back2reality
  776. Vibrato:       ; effect 'H'
  777.                checkpara0not
  778.                cmp      [channel.continueEf+si],1
  779.                je       norestart
  780.                mov      [channel.Tablepos+si],0
  781. norestart:     cmp      al,0
  782.                jne      newVibvalue
  783.                mov      al,[channel.VibPara+si]
  784. newVibValue:   mov      ah,al
  785.                shr      ah,4
  786.                cmp      ah,0
  787.                jne      Vibspeedok
  788.                mov      ah,[channel.VibPara+si]
  789.                and      ah,0f0h
  790.                or       al,ah
  791. VibspeedOk:    mov      [channel.VibPara+si],al
  792.                jmp      back2reality
  793. Tremor:        ; effect 'I'
  794.                checkPara0
  795.                jmp      back2reality
  796. Arpeggio:      ; effect 'J'
  797.                cmp      al,0
  798.                je       uselastPara
  799.                mov      [arp_chg],1
  800.                mov      [channel.parameter+si],al
  801.                jmp      back2reality
  802. uselastPara:   mov      [arp_chg],0
  803.                jmp      back2reality
  804. Vib_Vol:       ; effect 'K'
  805.                cmp      [channel.continueEf+si],1
  806.                je       volumeefcts
  807.                mov      [channel.Tablepos+si],0
  808.                jmp      volumeefcts
  809. Port_Vol:      ; effect 'L'
  810.                mov      [portaFlag],1
  811.                ; check first if portamento really possible:
  812.                cmp      [channel.enabled+si],0
  813.                je       stopporta             ; <- channel plays nothing -> no porta and volfx usefull ;)
  814.                cmp      [curNote],0feh
  815.                jae      volumeefcts           ; <- continue portamento
  816.                ; now save some values (we wanna slide from ...)
  817.                push     ax
  818.                mov      eax,[channel.sStep+si]
  819.                mov      [sStep_old],eax
  820.                mov      ax,[channel.sPeriod+si]
  821.                mov      [Period_old],ax
  822.                pop      ax
  823.                jmp      volumeefcts    ; <- and now volume effects
  824.  
  825. Retrigg:       ; effect 'Q'
  826.                cmp      al,0
  827.                jne      newretrPara
  828.                mov      al,[channel.parameter+si]
  829.                jmp      aftersetretr
  830. newretrPara:   mov      [channel.parameter+si],al
  831.                mov      ah,al
  832.                and      ah,0fh
  833.                cmp      ah,0
  834.                je       noretrigg
  835.                dec      ah
  836.                mov      [channel.ctick+si],ah
  837. aftersetretr:  mov      bl,al
  838.                shr      bl,4
  839.                shl      bl,1
  840.                xor      bh,bh
  841.                jmp      [retrig_dif+bx]
  842. nosld:         mov      [channel.cmd2nd+si],0
  843.                jmp      back2reality
  844. slddown:       mov      [channel.cmd2nd+si],2
  845.                jmp      back2reality
  846. use2div3:      mov      [channel.cmd2nd+si],4
  847.                jmp      back2reality
  848. use1div2:      mov      [channel.cmd2nd+si],6
  849.                jmp      back2reality
  850. sldup:         mov      [channel.cmd2nd+si],8
  851.                jmp      back2reality
  852. use3div2:      mov      [channel.cmd2nd+si],10
  853.                jmp      back2reality
  854. use2times:     mov      [channel.cmd2nd+si],12
  855.                jmp      back2reality
  856. noretrigg:     mov      [channel.command+si],0
  857.                jmp      back2reality
  858. Tremolo:       ; effect 'R'
  859.                cmp      [channel.continueEf+si],1
  860.                je       noTrmrestart
  861.                mov      [channel.Tablepos+si],0
  862. noTrmrestart:  cmp      al,0
  863.                jne      newTrmvalue
  864.                mov      al,[channel.Parameter+si]
  865. newTrmValue:   mov      ah,al
  866.                shr      ah,4
  867.                cmp      ah,0
  868.                jne      Trmspeedok
  869.                mov      ah,[channel.Parameter+si]
  870.                and      ah,0f0h
  871.                or       al,ah
  872. TrmspeedOk:    mov      [channel.Parameter+si],al
  873.                jmp      back2reality               
  874. Specialsets:   ; effect 'S'
  875.                checkPara0
  876.                xor      bh,bh
  877.                mov      bl,al
  878.                shr      bl,4
  879.                shl      bx,1
  880.                mov      [channel.cmd2nd+si],bx
  881.                ; do effects we have to check before reading note/vol/instr
  882.                jmp      [special1+bx]
  883. setvibwav:     ; for every channel a seperate choise !
  884.                and      al,3
  885.                add      al,al
  886.                xor      ah,ah
  887.                mov      bx,ax
  888.                shl      bx,1
  889.                mov      ax,[wavetab+bx]
  890.                mov      [channel.VibTabOfs+si],ax
  891.                jmp      back2reality
  892. settremwav:    ; for every channel a seperate choise !
  893.                and      al,3
  894.                add      al,al
  895.                xor      ah,ah
  896.                mov      bx,ax
  897.                shl      bx,1
  898.                mov      ax,[wavetab+bx]
  899.                mov      [channel.TrmTabOfs+si],ax
  900.                jmp      back2reality
  901. cmdPatloop:    and      al,0fh
  902.                cmp      al,0
  903.                je       set2where
  904.                cmp      [Ploop_on],1
  905.                je       alreadyinside
  906.                mov      [Ploop_on],1
  907.                inc      al
  908.                mov      [Ploop_no],al
  909. alreadyinside: mov      [Ploop_now],1
  910.                jmp      back2reality
  911. set2where:     mov      al,[curline]
  912.                mov      [Ploop_to],al
  913.                jmp      back2reality
  914. InitNotecut:   and      al,0fh
  915.                cmp      al,0
  916.                je       noCut
  917.                ;inc      al
  918.                mov      [channel.ndtick+si],al
  919.                jmp      back2reality
  920. noCut:         mov      [channel.command+si],9
  921.                jmp      back2reality
  922. InitNotedelay: and      al,0fh
  923.                mov      [channel.ndTick+si],al
  924.                cmp      [inpatterndly],1
  925.                je       donothing
  926.                mov      al,[curNote]      ; new note for later
  927.                mov      [channel.savnote+si],al
  928.                mov      al,[curInst]    ; new instrument for later
  929.                mov      [channel.savInst+si],al
  930.                mov      al,[curVol]    ; new volume for later
  931.                mov      [channel.savVol+si],al
  932.                jmp      donothing       ; setup note/instr/vol later while mixing !
  933. InitPatdelay:  cmp      [inpatterndly],1
  934.                je       back2reality            ; <- hehe we are allread in this patterndelay ...
  935.                and      al,0fh
  936.                inc      al
  937.                mov      [patterndelay],al
  938.                mov      al,[channel.parameter+si]
  939.                mov      [sav_para],al
  940.                jmp      back2reality
  941. setTempo:      ; effect 'T'
  942.                checkPara0not
  943.                xor      ah,ah
  944.                push     si di fs es
  945.                push     ax
  946.                call far ptr SET_TEMPO
  947.                pop      es fs di si
  948.                jmp      back2reality
  949.  
  950. globalvolume:  ; effect 'V'
  951.                checkPara0not
  952.                mov      [gvolFlag],1
  953.                cmp      al,64
  954.                jbe      gvolok
  955.                mov      al,64
  956. gvolok:        mov      [newgvol],al
  957.                jmp      back2reality
  958.  
  959. ;  _____________________________________
  960. ;  Effect after reading vol/instr/note :
  961. ;  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  962.  
  963. Hdl_Volfx:    ; effect 'D'
  964.               mov       bx,[channel.cmd2nd + si]
  965.               jmp       [vol_cmd2nd+bx]
  966. FineVSlideDwn:mov       al,[channel.Parameter+si]
  967.               and       al,0fh
  968.               sub       [channel.SampleVol+si],al
  969.               jnc       handlenothing
  970.               mov       [channel.SampleVol+si],0
  971.               jmp       handlenothing
  972. FineVSlideUp: mov       al,[channel.Parameter+si]
  973.               shr       al,4
  974.               add       [channel.SampleVol+si],al
  975.               cmp       [channel.SampleVol+si],64
  976.               jb        handlenothing
  977.               mov       [channel.SampleVol+si],63
  978.               jmp       handlenothing
  979. Hdl_pitchdwn: ; effect 'E'
  980.               mov       bx,[channel.cmd2nd + si]
  981.               jmp       [pitdwn_cmd2nd+bx]
  982. Finepitch_down:
  983.               ; we pitch down, but increase period ! (so check upper_border)
  984.               mov       ax,[channel.sPeriod+si]
  985.               mov       bl,[channel.Parameter+si]
  986.               and       bl,0fh
  987.               xor       bh,bh
  988.               shl       bx,2
  989.               add       ax,bx
  990.               cmp       ax,[channel.upper_border+si]
  991.               jb        ptok
  992.               mov       ax,[channel.upper_border+si]
  993. ptok:         ; now calc new frequency step for this period
  994.               mov       [channel.sPeriod+si],ax
  995.               CalcFrequStep
  996.               mov       ds:[channel.sStep+si],EAX
  997.               jmp       handlenothing
  998. XFinepitch_down:
  999.               ; we pitch down, but increase period ! (so check upper_border)
  1000.               mov       ax,[channel.sPeriod+si]
  1001.               mov       bl,[channel.Parameter+si]
  1002.               and       bl,0fh
  1003.               xor       bh,bh
  1004.               add       ax,bx
  1005.               cmp       ax,[channel.upper_border+si]
  1006.               jb        ptok
  1007.               mov       ax,[channel.upper_border+si]
  1008.               jmp       ptok
  1009. Hdl_pitchup:  ; effect 'F'
  1010.               mov       bx,[channel.cmd2nd + si]
  1011.               jmp       [pitup_cmd2nd+bx]
  1012. Finepitch_up: ; we pitch up, but decrease period ! (so check lower_border)
  1013.               mov       ax,[channel.sPeriod+si]
  1014.               mov       bl,[channel.Parameter+si]
  1015.               and       bl,0fh
  1016.               xor       bh,bh
  1017.               shl       bx,2
  1018.               sub       ax,bx
  1019.               cmp       ax,[channel.lower_border+si]
  1020.               ja        ptok
  1021.               mov       ax,[channel.lower_border+si]
  1022.               jmp       ptok
  1023. XFinepitch_up:; we pitch up, but decrease period ! (so check lower_border)
  1024.               mov       ax,[channel.sPeriod+si]
  1025.               mov       bl,[channel.Parameter+si]
  1026.               and       bl,0fh
  1027.               xor       bh,bh
  1028.               sub       ax,bx
  1029.               cmp       ax,[channel.lower_border+si]
  1030.               ja        ptok
  1031.               mov       ax,[channel.lower_border+si]
  1032.               jmp       ptok
  1033. Hdl_porta:     ; effect 'G'
  1034.                cmp      [curNote],0feh
  1035.                jae      handlenothing         ; <- is a portamento continue
  1036.                mov      ax,[Period_Old]
  1037.                xchg     ax,[channel.sPeriod+si]
  1038.                mov      [channel.wantedPeri+si],ax
  1039.                mov      eax,[sStep_old]
  1040.                mov      [channel.sStep+si],eax
  1041.                jmp      handlenothing
  1042. Hdl_Vibrato:   ; effect 'H'
  1043.                cmp      [channel.continueEf+si],1
  1044.                je       handlenothing                ; continue this effect !
  1045.                mov      ax,[channel.sPeriod+si]
  1046.                mov      [channel.OldPeriod+si],ax
  1047.                jmp      handlenothing
  1048. Hdl_arpeggio:  ; effect 'J'
  1049.                cmp      [arp_chg],1
  1050.                je       newPara
  1051.                cmp      [channel.continueEf+si],1
  1052.                je       handlenothing                ; no new note !
  1053.                ; start arpeggio:
  1054.                mov      [channel.ArpegPos+si],0
  1055. newPara:       mov      al,[channel.parameter+si]
  1056.                mov      ah,[channel.note+si]
  1057.                ; calc note 1:
  1058.                mov      bl,ah
  1059.                mov      bh,al
  1060.                shr      bh,4            ; upper 4 bits for note 1
  1061.                add      bl,bh
  1062.                mov      bh,bl
  1063.                and      bh,0f0h
  1064.                and      bl,00fh
  1065. arpt1:         cmp      bl,12
  1066.                jb       arpok1
  1067.                sub      bl,12
  1068.                add      bh,10h
  1069.                jmp      arpt1
  1070. arpok1:        or       bh,bl
  1071.                mov      [channel.note1+si],bh
  1072.                ; now note 2:
  1073.                mov      bl,ah
  1074.                mov      bh,al
  1075.                and      bh,0fh          ; lower 4 bits for note 2
  1076.                add      bl,bh
  1077.                mov      bh,bl
  1078.                and      bh,0f0h
  1079.                and      bl,00fh
  1080. arpt2:         cmp      bl,12
  1081.                jb       arpok2
  1082.                sub      bl,12
  1083.                add      bh,10h
  1084.                jmp      arpt2
  1085. arpok2:        or       bh,bl
  1086.                mov      [channel.note2+si],bh
  1087.                ; now calc the Steps:
  1088.                mov     ax,[channel.instrSEG+si]
  1089.                mov     fs,ax
  1090.                mov      al,[channel.Note+si]
  1091.                call near ptr calcpart
  1092.                mov      [channel.Step0+si],eax
  1093.                mov      al,[channel.Note1+si]
  1094.                call near ptr calcpart
  1095.                mov      [channel.Step1+si],eax
  1096.                mov      al,[channel.Note2+si]
  1097.                call near ptr calcpart
  1098.                mov      [channel.Step2+si],eax
  1099.                jmp      handlenothing
  1100.  
  1101. calcpart:      calcperiod
  1102.                cmp       ax,0
  1103.                je        nostep
  1104.                calcfrequStep
  1105.                retn
  1106. nostep:        xor       eax,eax
  1107.                retn
  1108.  
  1109. Hdl_Vib_Vol:   cmp      [channel.continueEf+si],1
  1110.                je       Hdl_Volfx
  1111.                mov      ax,[channel.sPeriod+si]
  1112.                mov      [channel.OldPeriod+si],ax
  1113.                jmp      Hdl_Volfx
  1114.  
  1115. Hdl_Port_Vol:  ; effect 'L'
  1116.                ; first handle Portamento (and then jump to volume effect handling)
  1117.                cmp      [curNote],0feh
  1118.                jae      Hdl_Volfx
  1119.                mov      ax,[Period_Old]
  1120.                xchg     ax,[channel.sPeriod+si]
  1121.                mov      [channel.wantedPeri+si],ax
  1122.                mov      eax,[sStep_old]
  1123.                mov      [channel.sStep+si],eax
  1124.                jmp       Hdl_Volfx
  1125. Hdl_setsmpofs:; effect 'O'
  1126.                xor       eax,eax
  1127.                mov       ah,[channel.parameter+si]
  1128.                mov       [channel.ssmpstart+si],ax
  1129.                shl       eax,16
  1130.                cmp       [curnote],0ffh
  1131.                je        handlenothing
  1132.                mov       [channel.sCurPos+si],eax
  1133.                jmp       handlenothing
  1134. Hdl_tremolo:  ; effect 'R' (Tremolo)
  1135.                cmp      [curInst],0
  1136.                jne      savevol                      ; new instrument
  1137.                cmp      [curVol],0ffh
  1138.                jne      savevol                      ; new volume
  1139.                cmp      [channel.continueEf+si],1
  1140.                je       handlenothing                ; continue this effect !
  1141.               ; save volume
  1142. savevol:      mov       al,[channel.SampleVol+si]
  1143.               mov       [channel.OldVolume+si],al
  1144.               jmp       handlenothing
  1145. Hdl_Special:  ; effect 'S'
  1146.               mov       bx,[channel.cmd2nd+si]
  1147.               jmp       [special2+bx]
  1148. Hdl_finetune: jmp       handlenothing
  1149. Hdl_patterndly: mov       al,[sav_para]
  1150.                 mov       [channel.parameter+si],al
  1151.                 mov       ax,[sav_cmd]
  1152.                 mov       [channel.command+si],ax
  1153.                 mov       [channel.cmd2nd+si],0
  1154.                 jmp       handlenothing
  1155.  
  1156. READNEWNOTES ENDP
  1157.  
  1158. ENDS
  1159.  
  1160. END